from collections import defaultdict,Counter
import math
import bisect
from itertools import accumulate
from math import ceil, log
from sys import stdin, stdout
def read():
return stdin.readline().rstrip()
total = int(read())
for q in range(total):
m = int(read())
g = True
d = defaultdict(lambda:[])
h = defaultdict(lambda:0)
mh = 0
for k in range(m):
i,j = ([int(p) for p in read().split()])
if i == j:
g = False
if g:
d[i] +=[k]
d[j] +=[k]
h[i] +=1
h[j] +=1
mh = max(mh,h[i],h[j])
if not g or mh > 2:
print("NO")
continue
e= defaultdict(lambda:[])
for k in d:
x = d[k]
for i in range(len(x)):
for j in range(i+1,len(x)):
e[x[i]] += [x[j]]
e[x[j]] += [x[i]]
color = [-1] * m
def dfs(i,c):
q = [(i,c)]
color[i] = c
while q:
curr, c = q.pop(-1)
nc = 1-c
for z in e[curr]:
if color[z] != -1:
if color[z] != nc:
return False
else:
color[z] = nc
q.append((z,nc))
return True
g= True
for i in range(m):
if color[i] ==-1:
x= dfs(i,0)
if not x:
g = False
break
if g :
print("YES")
else:
print("NO")
//#pragma GCC optimize("O1")
//#pragma GCC optimize("O2")
//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimize("O3,unroll-loops")
#include <bits/stdc++.h>
//#include <bits/extc++.h>
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
using namespace std;
//using namespace __gnu_pbds;
//using namespace __gnu_cxx;
//`````````````````````````````````````````````DEBUGGING``````````````````````````````````````````````````````
#define db1(x) cerr<<#x<<": "<<x<<"\n"
#define db2(x, y) cerr<<#x<<": "<<x<<" | "<<#y<<": "<<y<<"\n"
#define db3(x, y, z) cerr<<#x<<": " <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<"\n"
#define db4(a, b, c, d) cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<"\n"
#define db5(a, b, c, d, e) cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<<": "<<e<<"\n"
//````````````````````````````````````````````````````````````````````````````````````````````````````````````
//typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set ;
//typedef map < int , tree < int , null_type , less < int > , rb_tree_tag , tree_order_statistics_node_update > > indexed_map;
typedef unsigned long long ull;
typedef long double ld;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<pii> vpii;
typedef pair<ll, ll> pll;
typedef vector<ll> vl;
typedef vector<pll> vpll;
typedef vector<pair<char,int>> vpci;
typedef vector<pair<string,int>> vpsi;
typedef pair<char,int> pci;
typedef pair<string,int> psi;
typedef vector<vl> vll;
typedef priority_queue<ll> maxpq;
typedef priority_queue<ll, vl, greater<ll>> minpq;
#define FOR(i, a, b) for (ll i = a; i < b; i++)
#define REP(i,b,a) for(ll i=b-1;i>=a;i--)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pf push_front
#define ff first
#define ss second
#define sz(x) ((int)(x).size())
#define all(v) v.begin(), v.end()
#define rall(v) (v).rbegin(),(v).rend()
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fbo(a) find_by_order(a) //will give a-th largest element
#define ook(a) order_of_key(a) //will give no. of elements strictly lesser than a
#define sz(x) ((int)(x).size())
#define nzr(x) __builtin_clzll(x);
#define nzl(x) __builtin_ctzll(x);
#define setbits(x) __builtin_popcountll(x);
#define setbitsParity(x) __builtin_parityll(x); // 1 -> odd else 0 if even
#define umap unordered_map
#define uset unordered_set
#define endl "\n"
#define pi acos(-1)
#define PI 3.141592653589793238462643383279
#define E 2.71828
#define yes {cout << "YES" << endl; return;}
#define no {cout << "NO" << endl; return;}
#define YES {cout << "YES" << endl;}
#define NO {cout << "NO" << endl;}
#define nyet {cout<<"-1"<<endl;return;}
#define mxe(v) (*max_element(v.begin(),v.end()))
#define mne(v) (*min_element(v.begin(),v.end()))
#define unq(v) v.resize(distance(v.begin(), unique(v.begin(), v.end())));
#define psum(a,b) partial_sum(all(a),b.begin())
#define ub upper_bound
#define lb lower_bound
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) \
sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()
#define inarr(a, n) vl a(n,0);FOR(i, 0, n) cin >> a[i];
#define outarr(a) \
for(auto &it:a) \
cout << it << " "; \
cout << endl;
#define FAST_AF_BOI \
ios_base ::sync_with_stdio(0); \
cin.tie(0); \
cout.tie(0);
#define BUILT_DIFF freopen("input.txt","r",stdin);freopen("output.txt","w",stdout);
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;//abk
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
typedef unordered_map<ll,int,custom_hash> safe_map;
// ================================== i/o module ==================================
template <class T> void _print(T x){cerr<<x;};
template <class T, class V> void _print(pair <T, V> p);
template <class T> void _print(vector <T> v);
template <class T> void _print(set <T> v);
template <class T, class V> void _print(map <T, V> v);
template <class T> void _print(multiset <T> v);
template <class T, class V> void _print(pair <T, V> p) {cerr << "{"; _print(p.ff); cerr << ","; _print(p.ss); cerr << "}";}
template <class T> void _print(vector <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
template <class T> void _print(set <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
template <class T> void _print(multiset <T> v) {cerr << "[ "; for (T i : v) {_print(i); cerr << " ";} cerr << "]";}
template <class T, class V> void _print(map <T, V> v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";}
//void _print(pbds v) {cerr << "[ "; for (auto i : v) {_print(i); cerr << " ";} cerr << "]";}
template<typename typC,typename typD> istream &operator>>(istream &cin,pair<typC,typD> &a) { return cin>>a.first>>a.second; }
template<typename typC> istream &operator>>(istream &cin,vector<typC> &a) { for (auto &x:a) cin>>x; return cin; }
template<typename typC,typename typD> ostream &operator<<(ostream &cout,const pair<typC,typD> &a) { return cout<<a.first<<' '<<a.second; }
template<typename typC,typename typD> ostream &operator<<(ostream &cout,const vector<pair<typC,typD>> &a) { for (auto &x:a) cout<<x<<'\n'; return cout; }
template<typename typC> ostream &operator<<(ostream &cout,const vector<typC> &a) { int n=a.size(); if (!n) return cout; cout<<a[0]; for (int i=1; i<n; i++) cout<<' '<<a[i]; return cout; }
// ================================================================================
//`````````````````````````````````````````````IMP FUNCTIONS``````````````````````````````````````````````````````
ll ceil(ll a,ll b){return (a+b-1)/b;}
bool bit_check(ll x,int y){if((x & (1LL<<y))) return 1;return 0;}
ll bit_toggle(ll x,int y){return (x^(1LL<<y));}
ll LSB_clear(ll x, int y){return (x&(~((1<<(y+1))-1)));}
ll MSB_clear(ll x, int y){return (x&((1<<(y+1))-1));}
ll bit_sum(ll x,int y){return x+(1LL<<y);}
ll bit_sub(ll x,int y){return x-(1LL<<y);}
ll gcd(ll a, ll b) {if (b > a) {return gcd(b, a);} if (b == 0) {return a;} return gcd(b, a % b);}
ll bin_expo(ll a, ll b, ll mod) {ll res = 1; while (b > 0) {if (b & 1)res = (res * a) % mod; a = (a * a) % mod; b = b >> 1;} return res;}
ll bin_mul(ll a, ll b, ll mod) {ll res = 0; while (b > 0) {if (b & 1)res = (res + a) % mod; a = (a + a) % mod; b = b >> 1;} return res;}
void extendgcd(ll a, ll b, ll*v) {if (b == 0) {v[0] = 1; v[1] = 0; v[2] = a; return ;} extendgcd(b, a % b, v); ll x = v[1]; v[1] = v[0] - v[1] * (a / b); v[0] = x; return;} //pass an arry of size1 3
ll mminv(ll a, ll b) {ll arr[3]; extendgcd(a, b, arr); return arr[0];} //for non prime b
ll mminvprime(ll a, ll b) {return bin_expo(a, b - 2, b);}
bool revsort(ll a, ll b) {return a > b;}
ll combination(ll n, ll r, ll m, ll *fact, ll *ifact) {ll val1 = fact[n]; ll val2 = ifact[n - r]; ll val3 = ifact[r];if(n < r) return 0;if(n == r || r == 0) return 1;if(r<0) return 0; return (((val1 * val2) % m) * val3) % m;}
void google(int t) {cout << "Case #" << t << ": ";}
vl sieve(int n) {int*arr = new int[n + 1](); vl vect; for (int i = 2; i <= n; i++)if (arr[i] == 0) {vect.push_back(i); for (int j = 2 * i; j <= n; j += i)arr[j] = 1;} return vect;}
ll mod_add(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a + b) % m) + m) % m;}
ll mod_mul(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a * b) % m) + m) % m;}
ll mod_sub(ll a, ll b, ll m) {a = a % m; b = b % m; return (((a - b) % m) + m) % m;}
ll mod_div(ll a, ll b, ll m) {a = a % m; b = b % m; return (mod_mul(a, mminvprime(b, m), m) + m) % m;} //only for prime m
ll phin(ll n) {ll number = n; if (n % 2 == 0) {number /= 2; while (n % 2 == 0) n /= 2;} for (ll i = 3; i*i <= n; i += 2) {if (n % i == 0) {while (n % i == 0)n /= i; number = (number / i * (i - 1));}} if (n > 1)number = (number / n * (n - 1)) ; return number;} //O(sqrt(N))
ll large_expo(ll a,ll b,ll c,ll m) {return bin_expo(a,bin_expo(b,c,phin(m)),m);} //(a^b^c)%M
ll large_expo_prime(ll a,ll b,ll c,ll m) {return bin_expo(a,bin_expo(b,c,m-1),m);} //(a^b^c)%M when m is prime
vl prefixSum(vl v, bool flag){vl ans;ll sum = 0;if (flag){for (auto &e : v){sum += e;ans.eb(sum);}}else{REP(i, v.size(), 0){sum += v[i];ans.eb(sum);}}return ans;}
//````````````````````````````````````````````````````````````````````````````````````````````````````````````
const ll INF=9223372036854775103;
const int inf=2147483643;
const int N=1e5+10;
const int mod1=(1e9+7);
const int mod2=(998244353);
ll n,m,temp,sum,res,x,y,i,j,k,cost,idx,ind;
// bool flag1,flag2,flag3;
// string s,t,str;
class DSU {
public:
vl rank, parent, size, edges;
DSU(int n) {
rank.resize(n + 1, 0);
parent.resize(n + 1);
size.resize(n + 1);
edges.resize(n + 1, 0);
for (int i = 0; i <= n; i++) {
parent[i] = i;
size[i] = 1;
}
}
int findUPar(int node) {
if (node == parent[node])
return node;
return parent[node] = findUPar(parent[node]);
}
void unionByRank(int u, int v) {
int ulp_u = findUPar(u);
int ulp_v = findUPar(v);
if (ulp_u == ulp_v) {edges[ulp_u]++;return;}
if (rank[ulp_u] < rank[ulp_v]) {
parent[ulp_u] = ulp_v;
edges[ulp_v] += edges[ulp_u]+1;
}
else if (rank[ulp_v] < rank[ulp_u]) {
parent[ulp_v] = ulp_u;
edges[ulp_u] += edges[ulp_v]+1;
}
else {
parent[ulp_v] = ulp_u;
edges[ulp_u] += edges[ulp_v]+1;
rank[ulp_u]++;
}
}
void unionBySize(int u, int v) {
int ulp_u = findUPar(u);
int ulp_v = findUPar(v);
if (ulp_u == ulp_v) {edges[ulp_u]++;return;}
if (size[ulp_u] < size[ulp_v]) {
parent[ulp_u] = ulp_v;
size[ulp_v] += size[ulp_u];
edges[ulp_v]+=edges[ulp_u]+1;
}
else {
parent[ulp_v] = ulp_u;
size[ulp_u] += size[ulp_v];
edges[ulp_u]+=edges[ulp_v]+1;
}
}
};
void transcendent()
{
cin>>n;DSU ds(n);safe_map st;bool flag=true;FOR(i,0,n)
{
int u,v;cin>>u>>v;u--,v--;st[u]++,st[v]++;
if(u==v) flag=false;ds.unionBySize(u,v);
}
FOR(i,0,n)
{
if(st[i]!=2) flag=false;if(ds.size[ds.findUPar(i)]&1) flag=false;
}if(flag) yes no
}
int32_t main()
{
// BUILT_DIFF
FAST_AF_BOI
//cout << fixed << setprecision(7);
//cerr << fixed << setprecision(5);
//clock_t timer;
//timer = clock();
//PreComp();
int t=1;
cin >> t;
while (t--)
{
transcendent();
}
//timer = clock() - timer;
//double time_taken = ((double)timer) / CLOCKS_PER_SEC;
//cerr << "Processor time taken for the program : "
// << time_taken << " seconds " << endl;
return 0;
}
131C - The World is a Theatre | 1696A - NIT orz |
1178D - Prime Graph | 1711D - Rain |
534A - Exam | 1472A - Cards for Friends |
315A - Sereja and Bottles | 1697C - awoo's Favorite Problem |
165A - Supercentral Point | 1493A - Anti-knapsack |
1493B - Planet Lapituletti | 747B - Mammoth's Genome Decoding |
1591C - Minimize Distance | 1182B - Plus from Picture |
1674B - Dictionary | 1426C - Increase and Copy |
520C - DNA Alignment | 767A - Snacktower |
1365A - Matrix Game | 714B - Filya and Homework |
31A - Worms Evolution | 1691A - Beat The Odds |
433B - Kuriyama Mirai's Stones | 892A - Greed |
32A - Reconnaissance | 1236D - Alice and the Doll |
1207B - Square Filling | 1676D - X-Sum |
1679A - AvtoBus | 1549A - Gregor and Cryptography |